package com.hhrpc.hhrpc.core.consumer;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.hhrpc.hhrpc.core.api.RpcRequest;
import com.hhrpc.hhrpc.core.api.RpcResponse;
import com.hhrpc.hhrpc.core.utils.HhrpcMethodUtils;
import com.hhrpc.hhrpc.core.utils.TypeUtils;
import okhttp3.*;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;


import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.concurrent.TimeUnit;

public class HhRpcConsumerInvocationHandler implements InvocationHandler {

    private final String serviceName;



    public HhRpcConsumerInvocationHandler(String serviceName){
        this.serviceName=serviceName;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        RpcRequest request=new RpcRequest();
        request.setServiceName(serviceName);
        request.setArgs(args);
        request.setMethodSign(HhrpcMethodUtils.createMethodSign(method));
        //如果调用的方法是本地的方法  像toString这种就不要调用
        if(HhrpcMethodUtils.checkLocalMethod(method)){
            return  null;
        }
        RpcResponse rpcResponse=getRpcResponse(request,method.getReturnType());
        if(rpcResponse.getStatus()){
            return  rpcResponse.getData();
        }
        return null;
    }



    private  final OkHttpClient client=new OkHttpClient.Builder()
            .connectionPool(new ConnectionPool(16,60, TimeUnit.SECONDS))
            .connectTimeout(1,TimeUnit.SECONDS)
            .readTimeout(1,TimeUnit.SECONDS)
            .writeTimeout(1,TimeUnit.SECONDS).build();


    private RpcResponse getRpcResponse(RpcRequest request,Class<?>returnType)  {
        try {
            Gson gson = new Gson();
            String requestData = gson.toJson(request);

            Response response = client.newCall(new Request.Builder()
                    .url("http://localhost:8080/")
                    .post(RequestBody.create(MediaType.get("application/json; charset=utf-8"), requestData))
                    .build()).execute();

            String responseData = response.body().string();
            Class<?>realClazz= TypeUtils.cast(returnType);

            Type type = TypeToken.getParameterized(RpcResponse.class, realClazz).getType();
            RpcResponse rpcResponse = gson.fromJson(responseData, type);
            return  rpcResponse;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }
}
